package org.linlinjava.litemall.wx.feign;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.linlinjava.litemall.core.system.SystemConfig;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.LitemallAddress;
import org.linlinjava.litemall.db.domain.LitemallCart;
import org.linlinjava.litemall.db.domain.LitemallGroupon;
import org.linlinjava.litemall.db.domain.LitemallGrouponRules;
import org.linlinjava.litemall.db.domain.LitemallOrder;
import org.linlinjava.litemall.db.domain.LitemallOrderGoods;
import org.linlinjava.litemall.db.domain.LitemallProduct;
import org.linlinjava.litemall.db.service.LitemallAddressService;
import org.linlinjava.litemall.db.service.LitemallCartService;
import org.linlinjava.litemall.db.service.LitemallGrouponRulesService;
import org.linlinjava.litemall.db.service.LitemallGrouponService;
import org.linlinjava.litemall.db.service.LitemallOrderGoodsService;
import org.linlinjava.litemall.db.service.LitemallOrderService;
import org.linlinjava.litemall.db.service.LitemallProductService;
import org.linlinjava.litemall.db.service.LitemallRegionService;
import org.linlinjava.litemall.db.util.OrderHandleOption;
import org.linlinjava.litemall.db.util.OrderUtil;
import org.linlinjava.litemall.wx.annotation.LoginUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


/**
 * 订单
 * @author Administrator
 *
 */
@RestController
@RequestMapping("feign/order")
public class MallOrderController {

	private static final Logger logger = LoggerFactory.getLogger(MallOrderController.class);

	@Autowired
	private LitemallGrouponRulesService grouponRulesService;
	@Autowired
	private LitemallGrouponService grouponService;
	@Autowired
	private LitemallAddressService addressService;
	@Autowired
	private LitemallCartService cartService;
	@Autowired
	private PlatformTransactionManager txManager;
	@Autowired
	private LitemallOrderService orderService;
	@Autowired
	private LitemallRegionService regionService;
	@Autowired
	private LitemallOrderGoodsService orderGoodsService;
	@Autowired
	private LitemallProductService productService;

	/**
	 * 提交订单
	 * 1. 根据购物车ID、地址ID、优惠券ID，创建订单表项
	 * 2. 购物车清空
	 * 3. TODO 优惠券设置已用
	 * 4. 商品货品数量减少
	 *
	 * @param userId 用户ID
	 * @param body   订单信息，{ cartId：xxx, addressId: xxx, couponId: xxx }
	 * @return 订单操作结果
	 * 成功则 { errno: 0, errmsg: '成功', data: { orderId: xxx } }
	 * 失败则 { errno: XXX, errmsg: XXX }
	 */
	@PostMapping("/create")
	public Object create(@RequestBody Map<String, Object> params) {
		logger.info("创建商城订单。。。{}"+params);
		String userId = (String) params.get("customerId");
		String platformId = (String) params.get("platformId");
		String merchantId = (String) params.get("merchantId");
		String orderSn = (String) params.get("payOrderNo");
		String extMap = (String) params.get("extMap");

		Integer cartId = JacksonUtil.parseInteger(extMap, "cartId");
		Integer addressId = JacksonUtil.parseInteger(extMap, "addressId");
		Integer couponId = JacksonUtil.parseInteger(extMap, "couponId");
		Integer grouponRulesId = JacksonUtil.parseInteger(extMap, "grouponRulesId");
		Integer grouponLinkId = JacksonUtil.parseInteger(extMap, "grouponLinkId");

		//如果是团购项目,验证活动是否有效
		if (grouponRulesId != null && grouponRulesId > 0) {
			LitemallGrouponRules rules = grouponRulesService.queryById(grouponRulesId);
			//找不到记录
			if (rules == null) {
				return ResponseUtil.badArgument();
			}
			//团购活动已经过期
			if (grouponRulesService.isExpired(rules)) {
				return ResponseUtil.fail(402, "团购活动已过期!");
			}
		}

		if (cartId == null || addressId == null || couponId == null) {
			return ResponseUtil.badArgument();
		}

		// 收货地址
		LitemallAddress checkedAddress = addressService.findById(addressId);

		// 获取可用的优惠券信息
		// 使用优惠券减免的金额
		BigDecimal couponPrice = new BigDecimal(0.00);

		// 团购优惠
		BigDecimal grouponPrice = new BigDecimal(0.00);
		LitemallGrouponRules grouponRules  = null;
		if (grouponRulesId != null && grouponRulesId > 0) {
			grouponRules = grouponRulesService.queryById(grouponRulesId);
			if (grouponRules != null) {
				grouponPrice = grouponRules.getDiscount();
			}
		}

		// 货品价格
		List<LitemallCart> checkedGoodsList = null;
		if (cartId.equals(0)) {
			checkedGoodsList = cartService.queryByUidAndChecked(userId);
		} else {
			LitemallCart cart = cartService.findById(cartId);
			checkedGoodsList = new ArrayList<>(1);
			checkedGoodsList.add(cart);
		}
		if (checkedGoodsList.size() == 0) {
			return ResponseUtil.badArgumentValue();
		}
		BigDecimal checkedGoodsPrice = new BigDecimal(0.00);
		for (LitemallCart checkGoods : checkedGoodsList) {
			//  只有当团购规格商品ID符合才进行团购优惠
			if (grouponRules != null && grouponRules.getGoodsId().equals(checkGoods.getGoodsId())) {
				checkedGoodsPrice = checkedGoodsPrice.add(checkGoods.getPrice().subtract(grouponPrice).multiply(new BigDecimal(checkGoods.getNumber())));
			} else {
				checkedGoodsPrice = checkedGoodsPrice.add(checkGoods.getPrice().multiply(new BigDecimal(checkGoods.getNumber())));
			}
		}

		// 根据订单商品总价计算运费，满88则免运费，否则8元；
		BigDecimal freightPrice = new BigDecimal(0.00);
//		if (checkedGoodsPrice.compareTo(SystemConfig.getFreightLimit()) < 0) {
//			freightPrice = SystemConfig.getFreight();
//		}

		// 可以使用的其他钱，例如用户积分
		BigDecimal integralPrice = new BigDecimal(0.00);

		// 订单费用
		BigDecimal orderTotalPrice = checkedGoodsPrice.add(freightPrice).subtract(couponPrice);
		BigDecimal actualPrice = orderTotalPrice.subtract(integralPrice);

		// 开启事务管理
		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
		TransactionStatus status = txManager.getTransaction(def);
		Integer orderId = null;
		LitemallOrder order = null;
		try {
			// 订单
			order = new LitemallOrder();
			order.setUserId(userId);
			order.setOrderSn(orderSn);
			order.setAddTime(LocalDateTime.now());
			order.setOrderStatus(OrderUtil.STATUS_CREATE);
			order.setConsignee(checkedAddress.getName());
			order.setMobile(checkedAddress.getMobile());
			String detailedAddress = detailedAddress(checkedAddress);
			order.setAddress(detailedAddress);
			order.setGoodsPrice(checkedGoodsPrice);
			order.setFreightPrice(freightPrice);
			order.setCouponPrice(couponPrice);
			order.setIntegralPrice(integralPrice);
			order.setOrderPrice(orderTotalPrice);
			order.setActualPrice(actualPrice);
			order.setPlatformId(platformId);
			order.setMerchantId(merchantId);

			// 有团购活动
			if (grouponRules != null) {
				order.setGrouponPrice(grouponPrice);    //  团购价格
			} else {
				order.setGrouponPrice(new BigDecimal(0.00));    //  团购价格
			}

			// 添加订单表项
			orderService.add(order);
			orderId = order.getId();

			for (LitemallCart cartGoods : checkedGoodsList) {
				// 订单商品
				LitemallOrderGoods orderGoods = new LitemallOrderGoods();
				orderGoods.setOrderId(orderSn);
				orderGoods.setGoodsId(cartGoods.getGoodsId());
				orderGoods.setPlatformId(platformId);
				orderGoods.setMerchantId(merchantId);
				orderGoods.setGoodsSn(cartGoods.getGoodsSn());
				orderGoods.setProductId(cartGoods.getProductId());
				orderGoods.setGoodsName(cartGoods.getGoodsName());
				orderGoods.setPicUrl(cartGoods.getPicUrl());
				orderGoods.setPrice(cartGoods.getPrice());
				orderGoods.setNumber(cartGoods.getNumber());
				orderGoods.setSpecifications(cartGoods.getSpecifications());
				orderGoods.setAddTime(LocalDateTime.now());

				// 添加订单商品表项
				orderGoodsService.add(orderGoods);

				// 商品货品数量减少
				Integer productId = cartGoods.getProductId();
				LitemallProduct product = productService.findById(productId);

				Integer remainNumber = product.getNumber() - cartGoods.getNumber();
				if (remainNumber < 0) {
					throw new RuntimeException("下单的商品货品数量大于库存量");
				}
				product.setNumber(remainNumber);
				productService.updateById(product);
			}

			// 删除购物车里面的商品信息
			cartService.clearGoods(userId);

			//如果是团购项目，添加团购信息
			if (grouponRulesId != null && grouponRulesId > 0) {
				LitemallGroupon groupon = new LitemallGroupon();
				groupon.setOrderId(orderId);
				groupon.setPayed(false);
				groupon.setUserId(userId);
				groupon.setRulesId(grouponRulesId);

				//参与者
				if (grouponLinkId != null && grouponLinkId > 0) {
					//参与的团购记录
					LitemallGroupon baseGroupon = grouponService.queryById(grouponLinkId);
					groupon.setCreatorUserId(baseGroupon.getCreatorUserId());
					groupon.setGrouponId(grouponLinkId);
					groupon.setShareUrl(baseGroupon.getShareUrl());
					groupon.setPlatformId(platformId);
					groupon.setMerchantId(merchantId);
				} else {
					groupon.setCreatorUserId(userId);
					groupon.setGrouponId(0);
				}

				groupon.setAddTime(LocalDateTime.now());

				grouponService.createGroupon(groupon);
			}
		} catch (Exception ex) {
			txManager.rollback(status);
			logger.error("系统内部错误", ex);
			return ResponseUtil.fail(403, "下单失败");
		}
		txManager.commit(status);

		Map<String, Object> data = new HashMap<>();
		data.put("orderSn", orderSn);
		logger.info("创建商城订单。。。end{}"+data);
		return ResponseUtil.ok(data);
	}



	/**
	 * 修改订单状态
	 * @param params
	 * @return
	 */
	@PostMapping("/update")
	public Object update(@RequestBody Map<String, Object> params) {
		logger.info("修改订单状态...{}"+params);
		String orderSn = (String) params.get("payOrderNo");
		String txStatus = (String) params.get("txStatus");
		LitemallOrder order = orderService.findBySn(orderSn);
		if (order != null) {
			if ("00".equals(txStatus)) {
				order.setOrderStatus(OrderUtil.STATUS_PAY);
			}else if ("03".equals(txStatus)) {
				order.setOrderStatus(OrderUtil.STATUS_REFUND_CONFIRM);
			}else if ("04".equals(txStatus)) {
				order.setOrderStatus(OrderUtil.STATUS_REFUND);
			}else if ("01".equals(txStatus)) {
				order.setOrderStatus(OrderUtil.STATUS_CREATE);
			}
			orderService.update(order);
		}
		Map<String, Object> data = new HashMap<>();
		data.put("orderId", orderSn);
		return ResponseUtil.ok(data);
	}


	/**
	 * 订单申请退款
	 * 1. 检测当前订单是否能够退款
	 * 2. 设置订单申请退款状态
	 *
	 * @param userId 用户ID
	 * @param body   订单信息，{ orderId：xxx }
	 * @return 订单操作结果
	 * 成功则 { errno: 0, errmsg: '成功' }
	 * 失败则 { errno: XXX, errmsg: XXX }
	 */
	@PostMapping("/refund")
	public Object refund(@RequestBody Map<String, Object> params) {
		logger.info("订单申请退款...{}"+params);
		String orderSn = (String) params.get("orderSn");
		String userId = (String) params.get("userId");;

		LitemallOrder order = orderService.findBySn(orderSn);
		if (order == null) {
			return ResponseUtil.badArgument();
		}
		if (!order.getUserId().equals(userId)) {
			return ResponseUtil.badArgumentValue();
		}

		OrderHandleOption handleOption = OrderUtil.build(order);
		if (!handleOption.isRefund()) {
			return ResponseUtil.fail(403, "订单不能取消");
		}

		// 设置订单申请退款状态
		order.setOrderStatus(OrderUtil.STATUS_REFUND);
		orderService.update(order);
		Map<String, Object> data = new HashMap<>();
		data.put("orderId", orderSn);
		return ResponseUtil.ok(data);
	}


	private String detailedAddress(LitemallAddress litemallAddress) {
		Integer provinceId = litemallAddress.getProvinceId();
		Integer cityId = litemallAddress.getCityId();
		Integer areaId = litemallAddress.getAreaId();
		String provinceName = regionService.findById(provinceId).getName();
		String cityName = regionService.findById(cityId).getName();
		String areaName = regionService.findById(areaId).getName();
		String fullRegion = provinceName + " " + cityName + " " + areaName;
		return fullRegion + " " + litemallAddress.getAddress();
	}
}


